# -*- coding: utf-8 -*-
import sys
import time
import numpy
from PyQt5.QtWidgets import QMainWindow,QAbstractItemView,QMenu,QFileDialog,\
    QTreeWidget,QTreeWidgetItem,QApplication,QWidget
from PyQt5.QtGui import QIcon,QPixmap,QCursor
from PyQt5.QtCore import QByteArray,QThread,pyqtSignal
from Module.xRayDetection.xray.ftp import *
import queue
from Module.xRayDetection.xray.logs import Logger
from Module.xRayDetection.ftp_function import *
from Module.xRayDetection.xray.xray import run
from universal.root_path import dir_root,cvimg_to_qtimg
from mylibs.zoomWidget import ZoomWidget
import cv2
import numpy as np
from universal.custom.ini_file import ODvision_config,ODModule_config
from multiprocessing.dummy import Pool as ThreadPool
pic_tutle = ('jpg', 'png', 'jpeg', 'bmp','ico')

class Worker(QThread):
    sinOut = pyqtSignal(object,object)

    def __init__(self,path,item_,parent=None):
        super(Worker, self).__init__(parent)
        self.path = path
        self.item_ = item_
        self.lock = threading.RLock()

    def __del__(self):
        self.wait()

    def run(self):
        self.sinOut.emit(self.path, self.item_)

class TreeWidgetDemo(QMainWindow):
    loadImage = pyqtSignal(object)
    def __init__(self, parent=None):
        super(TreeWidgetDemo, self).__init__(parent)
        self.setWindowTitle('TreeWidget')
        self.tree = QTreeWidget()
        # 设置列数
        self.tree.setColumnCount(1)
        # 设置头的标题
        self.tree.setHeaderLabels(['Name'])
        self.tree.setHeaderHidden(True)
        self.setCentralWidget(self.tree)
        self.tree.setSelectionMode(QAbstractItemView.SelectionMode(3))

        self.setContextMenuPolicy(Qt.CustomContextMenu)  # 打开右键菜单的策略
        self.customContextMenuRequested.connect(self.TableEvent)  # 绑定事件

        self.initParameter()


    def initParameter(self):
        self.Ftp = None
        self.Path_Current = None
        self.canvas = None
        self.zoomWidget = ZoomWidget()
        self.zoomWidget.valueChanged.connect(self.paintCanvas)  #
        self.w1 = 1
        self.h1 = 1
        self.lock = threading.RLock()
        self.scrollArea = None
        self.scrollBars = None

        self.loadTreeItem = False
        self.isLoadPic = False
        self.Download_Path_5_Point = None
        self.loadImage.connect(self.loadImg_)
        self.Upload_Path_4_Ftp = None
        self.Download_Path_5_Ftp = None
        self.Input_Path_S = None
        self.loginButton = None
        self.tree.clicked.connect(lambda: self.OneClicked(False))

    def zoomRequest(self, delta):
        h_bar = self.scrollBars[Qt.Horizontal]
        v_bar = self.scrollBars[Qt.Vertical]
        h_bar_max = h_bar.maximum()
        v_bar_max = v_bar.maximum()
        cursor = QCursor()
        pos = cursor.pos()
        relative_pos = QWidget.mapFromGlobal(self.scrollArea, pos)
        cursor_x = relative_pos.x()
        cursor_y = relative_pos.y()
        w = self.scrollArea.width()
        h = self.scrollArea.height()
        margin = 0.1
        move_x = (cursor_x - margin * w) / (w - 2 * margin * w)
        move_y = (cursor_y - margin * h) / (h - 2 * margin * h)

        # clamp the values from 0 to 1
        move_x = min(max(move_x, 0), 1)
        move_y = min(max(move_y, 0), 1)

        # zoom in
        units = delta / (8 * 15)
        scale = 10
        self.addZoom(scale * units)

        # get the difference in scrollbar values
        # this is how far we can move
        d_h_bar_max = h_bar.maximum() - h_bar_max
        d_v_bar_max = v_bar.maximum() - v_bar_max
        new_h_bar_value = h_bar.value() + move_x * d_h_bar_max
        new_v_bar_value = v_bar.value() + move_y * d_v_bar_max
        h_bar.setValue(new_h_bar_value)
        v_bar.setValue(new_v_bar_value)

    def addZoom(self, increment=10):
        self.setZoom(self.zoomWidget.value() + increment)

    def setZoom(self, value):
        self.zoomWidget.setValue(value)


    def startThread(self,path,item):
        addThread = Worker(path,item)
        addThread.sinOut.connect(self.addTree)
        addThread.start()
# 1添加右键加入？
    def TableEvent(self):  #右键函数
        self.TreeItem = self.tree.selectedItems()
        if self.TreeItem!= []:
            popMenu = QMenu()
            act = popMenu.addAction('上传: 设为Ftp上传存储路径')
            act.triggered.connect(lambda: self.OneClicked(True, self.Upload_Path_4_Ftp))
            act = popMenu.addAction('下载: 设为Ftp下载路径')
            act.triggered.connect(lambda: self.OneClicked(True,self.Download_Path_5_Ftp))
            act = popMenu.addAction('下载: 设为下载中间节点路径')
            act.triggered.connect(lambda: self.OneClicked(True,self.Download_Path_5_Point))

            popMenu.exec_(QCursor.pos())

    def OneClicked(self,point,line=None):
        save_ = ''
        item = self.tree.currentItem()
        if item.text(0) == '/':
            self.Path_Current.setText('/')
        else:
            fullpath = self.parent_node(item,save_)
            self.Path_Current.setText(fullpath)
            try:
                if point:
                    if line.text() != '':
                        path = line.text() +","+fullpath
                    else:
                        path = fullpath
                    line.setText(path)
                else:
                    if self.Input_Path_S != None:
                        self.Input_Path_S.setText(fullpath)
            except Exception as e:
                pass

    def treeClickedThread(self,item_):
        if item_:
            item = item_
        else:
            item = self.tree.currentItem()

        if item.isExpanded():
            item.setExpanded(False)
        else:
            item.setExpanded(True)

        if item.text(0) == '/':
            item.setExpanded(True)

        # print("key=%s ,value=%s" % (item.text(0), item.text(1)))
        if '加载中' not in item.text(0):
            if item.parent() == None and item.childCount() == 0:
                self.addTreeNodeBtn(item.text(0), item)
            else:
                if item.childCount() == 0:
                    save_ = ''
                    fullpath = self.parent_node(item, save_)
                    time1 = time.time()
                    ret = re.search("\.\w{2,4}$", fullpath)
                    print("self.Ftp.isdir:", time.time() - time1)
                    if ret:
                        if fullpath.endswith(pic_tutle):
                            if self.isLoadPic:
                                return
                            DownloadPic = threading.Thread(target=self.Download_Pic, args=(fullpath,))
                            DownloadPic.daemon = True
                            DownloadPic.start()
                        else:
                            return
                    else:
                        self.addTreeNodeBtn(fullpath, None)

                # isdir = self.Ftp.isdir(fullpath)
                # print("self.Ftp.isdir:",time.time() - time1)
                # if item.childCount() == 0 and isdir:
                #     self.addTreeNodeBtn(fullpath, None)
                # elif item.childCount() == 0 and not isdir:
                #     if self.isLoadPic == True:
                #         return
                #     DownloadPic = threading.Thread(target=self.Download_Pic, args=(fullpath,))
                #     DownloadPic.daemon = True
                #     DownloadPic.start()

    def onTreeClicked(self,item_):
        treeThread = threading.Thread(target=self.treeClickedThread, args=(item_,))
        treeThread.daemon = True
        treeThread.start()

        # save_ = ''
        # if item_:
        #     item = item_
        # else:
        #     item = self.tree.currentItem()
        #
        # if item.isExpanded():
        #     item.setExpanded(True)
        # else:
        #     item.setExpanded(False)
        #
        # if item.text(0) == '/':
        #     item.setExpanded(True)
        #
        # print("key=%s ,value=%s" % (item.text(0), item.text(1)))
        # if '加载中' not in item.text(0):
        #     if item.parent() == None and item.childCount() == 0:
        #         self.addTreeNodeBtn(item.text(0),item)
        #     else:
        #         save_ = ''
        #         fullpath = self.parent_node(item,save_)
        #         isdir = self.Ftp.isdir(fullpath)
        #         if item.childCount() == 0 and isdir:
        #             self.addTreeNodeBtn(fullpath,None)
        #         elif item.childCount() == 0 and not isdir:
        #             self.DownloadPic = threading.Thread(target=self.Download_Pic, args=(fullpath,))
        #             self.DownloadPic.daemon = True
        #             self.DownloadPic.start()

    def Download_Pic(self,fullpath):
        try:
            time1 = time.time()
            self.isLoadPic = True
            bio = self.Ftp.download(download_path=fullpath)
            data = bio.getvalue()
            self.loadImage.emit(data)
            QApplication.processEvents()
            self.isLoadPic = False
            print("Ftp.download time is ", time.time() - time1)
        except Exception as e:
            self.isLoadPic = False
            print(str(e))

    def byte2img(self,bio):
        im = np.asarray(bytearray(bio))
        img = cv2.imdecode(im,cv2.IMREAD_COLOR)
        img = cvimg_to_qtimg(img,True)
        return img

    def parent_node(self,item,save_):
        node = item.parent()     #获取父节点
        if save_ == '':
            save = item.text(0)
        else:
            save = item.text(0) + '/' + save_
        save_ = save
        if node.parent() == None :
            if node.text(0) == '/':
                path = '/' + save_
            else:
                path = node.text(0) + '/' +save_
        else:
            path = self.parent_node(node,save_)
        return path

    def process(self,path_,path,item):

        xx = QTreeWidgetItem(item)
        xx.setText(0, path_['name'])
        whole_path = os.path.join(path,path_['name'])
        if whole_path.endswith(pic_tutle):
            xx.setIcon(0, QIcon(":icons/pic.png"))
        elif not path_['file']:
            xx.setIcon(0, QIcon(":icons/dir.png"))
        else:
            xx.setIcon(0, QIcon(":icons/txt.png"))

    def addTreeNodeBtn(self,path,item_):
        if self.loadTreeItem == True:
            return
        if item_:
            GetThread = threading.Thread(target=self.addTree, args=(path, item_))
        else:
            item = self.tree.currentItem()
            GetThread = threading.Thread(target=self.addTree, args=(path, item))
        GetThread.daemon = True
        GetThread.start()

    def processItem(self,path_list, path, item):
        time1 = time.time()
        for path_ in path_list:
            xx = QTreeWidgetItem(item)
            xx.setText(0, path_['name'])
            whole_path = os.path.join(path, path_['name'])
            if whole_path.endswith(pic_tutle):
                xx.setIcon(0, QIcon(":icons/pic.png"))
            elif not path_['file']:
                xx.setIcon(0, QIcon(":icons/dir.png"))
            else:
                xx.setIcon(0, QIcon(":icons/txt.png"))
            QApplication.processEvents()
        self.loadTreeItem = False
        print("QTreeWidgetItem time is ", time.time() - time1)

    def addTree(self, path, item):
        self.loadTreeItem = True
        xx = QTreeWidgetItem(item)
        xx.setText(0, '加载中......')
        self.loginButton.setEnabled(False)
        path_list = self.Ftp.listdir(path, parse=True)  #
        Len_list = len(path_list)
        item.removeChild(xx)
        self.processItem(path_list, path, item)
        self.loginButton.setEnabled(True)
        # time1 = time.time()
        # pool = ThreadPool(4)
        # results = [pool.apply(self.process, args=(row, path, item)) for row in path_list]
        # pool.close()
        # pool.join()
        # self.loadTreeItem = False
        # print("QTreeWidgetItem time is ", time.time() - time1)

        # time1 = time.time()
        # for i in range(Len_list):
        #     # time.sleep(0.0001)
        #     xx = QTreeWidgetItem(item)
        #     xx.setText(0, path_list[i]['name'])
        #     whole_path = os.path.join(path, path_list[i]['name'])
        #     if whole_path.endswith(pic_tutle):
        #         xx.setIcon(0, QIcon(":icons/pic.png"))
        #     elif not path_list[i]['file']:
        #         xx.setIcon(0, QIcon(":icons/dir.png"))
        #     else:
        #         xx.setIcon(0, QIcon(":icons/txt.png"))
        # self.loadTreeItem = False
        # print("QTreeWidgetItem time is ",time.time() - time1)

   #============图像=============
    def drawDetectBox(self,Img,Box_list):
        height = Img.shape[0]
        width = Img.shape[1]
        if len(Box_list) < 1:
            cv2.putText(Img, "OK", (int(width - width / 2),
                                    int(height / 7)), cv2.FONT_HERSHEY_PLAIN, 2.0,
                        (0, 255, 0), 2)
        else:
            for box in Box_list:
                x1 = box[0]
                y1 = box[1]
                x2 = box[2]
                y2 = box[3]
                conf = round(box[4], 3)
                cls = box[6]
                conf_cls = '%s %s' % (cls, conf)
                cv2.rectangle(Img, (x1, y1), (x2, y2), (255, 55, 55), thickness=2)
                cv2.putText(Img, conf_cls, (x1, y1),
                            cv2.FONT_HERSHEY_COMPLEX, 1.0, (0, 255, 0), thickness=2)
            cv2.putText(Img, "NG", (int(width - width / 2),
                                    int(height / 7)), cv2.FONT_HERSHEY_PLAIN, 5.0, (0, 0, 255), 2)
        return Img
    def paintCanvas(self):
        self.canvas.scale = 0.01 * self.zoomWidget.value()#
        self.canvas.adjustSize()
        self.canvas.update()

    def scaleFitWindow(self):
        a1 = self.w1 / self.h1
        w2 = self.canvas.pixmap.width() - 0.0
        h2 = self.canvas.pixmap.height() - 0.0
        print('w2:',w2,h2)
        a2 = w2 / h2
        return self.w1 / w2 if a2 >= a1 else self.h1 / h2

    def adjustScale(self):
        value = self.scaleFitWindow()
        self.zoomWidget.setValue(int(100 * value))

    def loadImg_(self, qImg):
        try:
            pixmap = QPixmap()
            pixmap.loadFromData(qImg)
            self.canvas.loadPixmap(pixmap)
            self.adjustScale()
            self.paintCanvas()
        except Exception as e:
            print(str(e))

    def loadImg(self, qImg):
        try:
            A1= time.time()
            pixmap = QPixmap.fromImage(qImg)
            self.canvas.loadPixmap(pixmap)
            self.adjustScale()
            self.paintCanvas()
            print("loadimg:",time.time()-A1)
        except Exception as e:
            print(str(e))
    #---------------------------------------

# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     tree = TreeWidgetDemo()
#     tree.show()
#     sys.exit(app.exec_())